function* asyncGenerator() {
    yield new Promise((resolve) => setTimeout(resolve, 1000, 'First result'));
    yield new Promise((resolve) => setTimeout(resolve, 1000, 'Second result'));
    yield 'Third result';
    // return 'final';
}

// async function asyncGenerator() {
//     await new Promise((resolve) => setTimeout(resolve, 1000, 'First result'));
//     await new Promise((resolve) => setTimeout(resolve, 1000, 'Second result'));
//     return 'Third result';
// }

let g = asyncGenerator();

/**
 * 下面这组代码会返回正确的顺序：
 * First result
 * Second result
 * Third result
 */

// g.next()
//     .value.then(console.log)
//     .then(() => g.next().value)
//     .then(console.log)
//     .then(() => console.log(g.next().value));

/**
 * 下面这组代码，会先返回Third，再同时返回First和Second
 * Third result
 * First result
 * Second result
 *
 */

// let p = g.next().value;
// p.then(console.log);

// p = g.next().value;
// p.then(console.log);

// console.log(g.next().value);

/**
 * cancellable函数主体
 */

function cancellable(generatorFunc) {
    let cancel = false;
    let iterator = generatorFunc();

    function run(result) {
        return new Promise((res, rej) => {
            if (cancel) {
                rej(new Error('Cancelled'));
            } else {
                let ret = iterator.next(result);
                if (!!ret.value.then) ret.value.then(res);
                else {
                    res(ret.value);
                }
            }
        });
    }

    function cancelFunc() {
        cancel = true;
    }

    return [cancelFunc, run];
}

const [cancelFunc, pIter] = cancellable(asyncGenerator);
pIter()
    .then(console.log)
    .then(pIter)
    .then(console.log)
    .then(pIter)
    .then(console.log);

// pIter().then(() => cancelFunc);

/**
 * backup 下面的代码不要动
 */

// function cancellable(generatorFunc) {
//     let cancel = false;
//     const iterator = generatorFunc();

//     function run(result) {
//         return new Promise((resolve, reject) => {
//             if (cancel) {
//                 reject(new Error('Cancelled'));
//             } else {
//                 let generatorResult;
//                 try {
//                     generatorResult = iterator.next(result);
//                 } catch (error) {
//                     reject(error);
//                     return;
//                 }

//                 if (generatorResult.done) {
//                     resolve(generatorResult.value);
//                 } else {
//                     generatorResult.value.then(run).catch(reject);
//                 }
//             }
//         });
//     }

//     function cancelFunc() {
//         cancel = true;
//     }

//     const promise = run().catch((error) => {
//         if (error.message !== 'Cancelled') {
//             throw error;
//         }
//     });

//     return [cancelFunc, promise];
// }

// function* asyncGenerator() {
//   yield new Promise((resolve) => setTimeout(resolve, 1000, 'First result'));
//   yield new Promise((resolve) => setTimeout(resolve, 1000, 'Second result'));
//   yield 'Third result';
// }

// const [cancel, promise] = cancellable(asyncGenerator);

// promise.then(console.log).catch(console.error);

// 在某个时间点取消操作
// cancel();
